]> dgit.raspbian.org Git - libreoffice.git/commitdiff
[PATCH] match the package content provider when checking a vnd.sun.star.pkg url
authorCaolán McNamara <caolan.mcnamara@collabora.com>
Fri, 12 Jun 2026 20:32:27 +0000 (20:32 +0000)
committerRene Engelhard <rene@debian.org>
Tue, 21 Jul 2026 16:41:22 +0000 (13:41 -0300)
IsExoticProtocol used GetHost() to recover the nested package url of a
vnd.sun.star.pkg url, but the package content provider in
ucb/source/ucp/package/pkguri.cxx uses the whole authority between "://"
and the next '/', which GetHost() truncates at '@'. Check the same
substring the provider does.

The vnd.sun.star.zip branch below already did the equivalent extraction,
so pull the shared parts into a helper that both branches call.

Signed-off-by: Caolán McNamara <caolan.mcnamara@collabora.com>
Change-Id: I27be6a839108f2e58d62baefc1a71dcbfc9a4568
Reviewed-on: https://gerrit.collaboraoffice.com/c/online/+/4410
Tested-by: Jenkins CPCI <releng@collaboraoffice.com>
Reviewed-by: Stephan Bergmann <stephan.bergmann@collabora.com>
(cherry picked from commit ce436efb34d2e0e90ee2cdb450da285530c562f7)
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/206681
Reviewed-by: Xisco Fauli <xiscofauli@libreoffice.org>
Tested-by: Jenkins
(cherry picked from commit 4ba5567cc44be760066c0c45c99949f790cf181a)
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/206701

Gbp-Pq: Name CVE-2026-63278.diff

tools/qa/cppunit/test_urlobj.cxx
tools/source/fsys/urlobj.cxx

index 31347cf4b576bacdb81d1f2a69c6c94a95abdf13..949b2ac155cbe4dc5517e62a83d582d81da271bc 100644 (file)
@@ -370,6 +370,11 @@ namespace tools_urlobj
                 CPPUNIT_ASSERT_EQUAL(INetProtocol::VndSunStarPkg, url.GetProtocol());
                 CPPUNIT_ASSERT(!url.IsExoticProtocol());
             }
+            {
+                INetURLObject url(u"vnd.sun.star.pkg://vnd.sun.star.expand%3Ahttp%3A%2F%2F127.0.0.1%2F%24%7BHOME%7D@example.com/x");
+                CPPUNIT_ASSERT_EQUAL(INetProtocol::VndSunStarPkg, url.GetProtocol());
+                CPPUNIT_ASSERT(url.IsExoticProtocol());
+            }
             {
                 INetURLObject url(u"vnd.sun.star.zip://slot%3A0");
                 CPPUNIT_ASSERT_EQUAL(INetProtocol::Generic, url.GetProtocol());
index 7f6e43cfc32242fafe1f01de51bb2357ece9efed..91b33437c606519866a624431b5d4af2868f190b 100644 (file)
@@ -4887,6 +4887,25 @@ OUString INetURLObject::CutExtension()
     return OUString();
 }
 
+namespace {
+
+// Treat the substring of rURL from nStart up to the next '/' or '?' as a
+// percent-encoded nested url and report whether that nested url is an
+// exotic protocol.
+bool isExoticNestedProtocol(const OUString& rURL, sal_Int32 nStart)
+{
+    auto const find = [&rURL, nStart](auto c) {
+        auto const n = rURL.indexOf(c, nStart);
+        return n == -1 ? rURL.getLength() : n;
+    };
+    return INetURLObject(
+               INetURLObject::decode(rURL.subView(nStart, std::min(find('/'), find('?')) - nStart),
+                                     INetURLObject::DecodeMechanism::WithCharset))
+        .IsExoticProtocol();
+}
+
+}
+
 bool INetURLObject::IsExoticProtocol() const
 {
     if (m_eScheme == INetProtocol::Slot ||
@@ -4899,8 +4918,16 @@ bool INetURLObject::IsExoticProtocol() const
         return true;
     }
     if (m_eScheme == INetProtocol::VndSunStarPkg) {
-        return INetURLObject(GetHost(INetURLObject::DecodeMechanism::WithCharset))
-            .IsExoticProtocol();
+        // The package content provider (ucb/source/ucp/package/pkguri.cxx)
+        // treats the whole authority between "://" and the next '/' as the
+        // nested package url. GetHost() returns only the part after any '@',
+        // so match the provider and check that substring instead.
+        OUString sPayloadURL = GetMainURL(INetURLObject::DecodeMechanism::NONE);
+        sal_Int32 nStart = sPayloadURL.indexOf(u"://");
+        if (nStart == -1) {
+            return false;
+        }
+        return isExoticNestedProtocol(sPayloadURL, nStart + 3);
     }
     if (isSchemeEqualTo(u"vnd.sun.star.zip"))
     {
@@ -4908,11 +4935,7 @@ bool INetURLObject::IsExoticProtocol() const
         if (!sPayloadURL.startsWith(u"//")) {
             return false;
         }
-        auto const find = [&sPayloadURL](auto c) {
-            auto const n = sPayloadURL.indexOf(c, 2);
-            return n == -1 ? sPayloadURL.getLength() : n;
-        };
-        return INetURLObject(decode(sPayloadURL.subView(2, std::min(find('/'), find('?')) - 2), INetURLObject::DecodeMechanism::WithCharset)).IsExoticProtocol();
+        return isExoticNestedProtocol(sPayloadURL, 2);
     }
     return false;
 }